#include "DataHandler.h"
#include "utils.h"


DataHandler::DataHandler() {
    _data_loaded = false;
}

DataHandler::DataHandler(ifstream &ifs) {
    string buffer;
    istream& is(ifs);

    while ( is.good() ) {
        vector<string> vec_temp;
        string name_temp;

        getline(is , buffer);
        if ( ! is.good() ) {
            break;
        }

        vec_temp = split(buffer, ' ');
        // vec_temp => [ "minecraft" , "0" , "1" , "2" , "3" , "4" , "5" , "6" , "7" ]
        name_temp = vec_temp[0];
        vec_temp.erase(vec_temp.begin());

        addtodatamap( this->_data_map, name_temp, vec_temp);
        
    }

    _data_loaded = true;
}


// Public methods
Queryset DataHandler::query(enum QUERY_TYPE type, string key1, string key2) const {
    Queryset key1_query, key2_query;
    Queryset::iterator it;


    if ( has_key(_data_map, key1) ) {
        key1_query = _data_map.find(key1)->second;
    } else {
        key1_query = Queryset(0);
    }
    if ( has_key(_data_map, key2) ) {
        key2_query = _data_map.find(key2)->second;
    } else {
        key2_query = Queryset(0);
    }

    Queryset result(key1_query.size() + key2_query.size());

    sort ( key1_query.begin() , key1_query.end());
    sort ( key2_query.begin() , key2_query.end());


    switch ( type ) {
        case DIFFERENCE:
            it = set_difference(key1_query.begin(), key1_query.end(), key2_query.begin(), key2_query.end(), result.begin());
            break;
        case INTERSECTION:
            it = set_intersection(key1_query.begin(), key1_query.end(), key2_query.begin(), key2_query.end(), result.begin());
            break;
        case UNION:
            it = set_union(key1_query.begin(), key1_query.end(), key2_query.begin(), key2_query.end(), result.begin());
            break;
    }

    Queryset filtered_result ( result.begin() , it );

    return filtered_result;

}

void DataHandler::query_print(enum QUERY_TYPE type, string key1, string key2) const {
	Queryset result = this->query(type, key1, key2);

	if ( result.size() == 0 ) {
		cout << "Not found." << endl;
	} else {
		for (Queryset::iterator i = result.begin() ; i < result.end() ; ++i ) {
			cout << (*i) << " ";
		}
		cout << endl;
	}

}

